:- module(results_page,
	[
	    results_page/3
	],
	[pillow,assertions,regtypes,basicmodes]).

:- use_module(library(lists), [length/2, append/3]).
:- use_module(library(terms)).
:- use_module(library('pillow/pillow_types')).

:- use_module(amos(configuration), [wdbn_url/1]).

:- use_module(search(utils), [
        split_in_lines/2,
        log_message/1,
        split_llist_into_atoms/2,
        new/2,
        atom_concat_with_dollars/2]).
:- use_module(portalfiles(standard_page), [standard_page/5]).
:- use_module(portalfiles(web_utils), [generate_box/2]).
:- use_module(search(match_interface), [values/1, results/1]).

:- comment(module,"This module generates a HTML page that contains
	resulting assemblies of a given query. This HTML page is
	embedded in the general search form page (generated by
	form_page), in order to allow sequences of queries.").

:- true pred results_page(in(Values), in(Results), go(HTML)) :: values
   * results * html_term

# "Translates the search results stored in @var{Results} plus the
   search parameters @var{Values} given by the user in the search form
   to a formatted HTML view @var{HTML}".

results_page(values(Terms, Ini, NumOfMatches, _Timeout, _SortMethod, _Mode, InP, ExP),
                results(LResults, Total, Time),
		HTML) :-
        log_message(results_page_body_2),
        log_message(starting_summary_page(LResults)),
        HTML = [
                   PreviousInfo,
                   SearchResults,
		   Buttons
	       ],
	prev_next_buttons(Ini, NumOfMatches, Total, Buttons),
	optional_text("Packages to be included: ", InP, InPText),
	optional_text("Packages to be excluded: ", ExP, ExPText),
	PreviousInfo = [
			   ResultText,
			   p$[],
			   InPText,
			   ExPText
		       ],
	First is Ini + 1,
	length(LResults, RealNum),
	Last is First + RealNum - 1,
        % Result text
	result_text(First, Last, Total, Time, Terms, ResultText),
	% Search text
        log_message('Generating package HTML code'(LResults)), 
        result_htmls(LResults, Ini, SearchResults),
	log_message('Summary Search Page generated.').

result_text(First, Last, Total, Time, Terms, HTML) :-
	number_codes(First, FirstStr),
	number_codes(Last, LastStr),
	time_text(Time, TimeText),
	( Total = 0 ->
	    CountStr = ["No results found"]
        ;
	    number_codes(Total, TotalStr),
	    CountStr = ["Results ", font([], b(FirstStr)), "-", 
	                font([], b(LastStr)), 
		        " of ", font([], b(TotalStr))]
	), 
	HTML0 = [CountStr, " for ", 
		 font([], b(Terms)), ". ", TimeText],
	HTML = [
		   begin(table, [cols="1", border="0", width="100%", style="border-top: 1px solid #cc9235; color:#0f4e60;"]), nl,
		   begin(tbody), nl,
		   tr$[bgcolor="#e9e8e4"],nl,
		   td([align="center"], HTML0),
		   end(tr), nl,
		   end(tbody),
		   end(table)
               ].

time_text(Time, TimeText) :-
        time_codes(Time, TimeStr),
	TimeText = ["(", font([], b(TimeStr)), " seconds)"].

optional_text(Name, Text, HTML) :-
	( Text = '' ->
            HTML = []
	;
            HTML = [
		       font([],b(Name)),
		       b(Text),
		       p$[]
		   ]
	).

result_htmls([], _, []).
result_htmls([P|Ps], I, [HTML|Hs]):-
%	??? P = match_result(_Flooded, _Capabilities, PackagesStr),
%	??? split_llist_into_atoms(PackagesStr, Packages),
	result_html(P, I, HTML),
	I1 is I + 1,
	result_htmls(Ps, I1, Hs).

%% To select the database to use.
:- include(which_match_to_use).

% Translate a match_result/3 to HTML code
result_html(Key-match_result(Flooded, Capabilities, Packages), I, HTML) :-
        log_message(result_html),
        split_in_lines_link(Packages, PackagesSpl),
	I1 is I + 1, number_codes(I1, IStr), % get solution number string
	percent_codes(Key, KeyStr), % get score string (as key string)
        cap_list_to_html(Flooded, FloodedSpl),
	optional_row("Unmatched:", FloodedSpl, OptFlooded),
        cap_list_to_html(Capabilities, CapabilitiesSpl),
	optional_row("Fulfilled:", CapabilitiesSpl, OptCapabilities),
        HTML = [
		   font([], env(h3, [], ["Solution #", IStr, " (relative score ", KeyStr, ")"])),
		   p$[], 
		   begin(table, [cols="2"]),
		   begin(tbody, [valign="baseline", align="left"]),
		   begin(tr, [valign="baseline", align="left"]),
		   begin(td, [style="width:9em"]),
		   b("Packages:"),
		   end(td),
		   begin(td),
		   PackagesSpl,
		   end(td),
		   end(tr),
		   OptFlooded,
		   OptCapabilities,
		   end(tbody),
		   end(table)
	       ].

optional_row(Name, Text, HTML) :-
	( Text = [] ->
	    HTML = []
	; HTML = [
		     begin(tr, [valign="baseline", align="left"]),
		     begin(td, [style="width:9em"]),
		     b(Name),
		     end(td),
		     begin(td),
		     Text,
		     end(td),
		     end(tr)
		 ]
	).

percent_codes(Key, KeyStr) :-
	Big is integer(Key * 100),
	number_codes(Big, BigStr),
	append(BigStr, "%", KeyStr).

time_codes(Time, TimeStr) :-
	Big is integer(Time / 1000),
	Small1 is integer(Time / 100) mod 10,
	Small2 is round(Time / 10) mod 10,
	number_codes(Big, BigStr),
	number_codes(Small1, [S1]),
	number_codes(Small2, [S2]),
	append(BigStr, "."||[S1, S2], TimeStr).

% Format a list of packages
split_in_lines_link([], []).
split_in_lines_link([A|As], [A2, ' '|Bs]):-
	get_package_link(A, A2),
	split_in_lines_link(As, Bs).

cap_list_to_html([], []).
cap_list_to_html([A0|As], [A, ' '|Bs]) :-
	cap_to_html(A0, A),
	cap_list_to_html(As, Bs).

cap_to_html((C, L), Html) :-
	( L = [] ->
	    Html = [C]
	; Html = [C, ' ', span([style='color:#777'], [CapHistoryHtml])],
	  caphistory_to_html(L, CapHistoryHtml)
	).

caphistory_to_html([], []).
caphistory_to_html([H0|Hs0], [' &lArr; ', H|Hs]) :-
	caphistory_to_html__2(H0, H),
	caphistory_to_html(Hs0, Hs).

caphistory_to_html__2(h(T, C), Html) :-
	( T = spe -> Html = span([style='color:#04f'], ['s:', C])
	; T = gen -> Html = span([style='color:#f40'], ['u:', C])
	).

get_package_link(Name, HTML) :-
	HTML = env(a, [href=Link], Name),
	wdbn_url(URL), 
	resource_name_to_key([Name],[Key]),
	atom_concat([URL, '/webdb_client.cgi?key=', Key, '&service=show_package'], Link).

% Previous/Next buttons
prev_next_buttons(Ini, NumOfMatches, Total, Buttons) :-
        % Previous button needed?
	( Ini > 0 ->
	    Previous = b(input(submit, [name=prev_ini, value="Previous"]))
	; Previous = '&nbsp'
	),
        % Next button needed?
	( NextIni is Ini + NumOfMatches, Total > NextIni ->
	    Next = b(input(submit, [name=next_ini, value="Next"]))
	; Next = '&nbsp'
	),
	Buttons = [
		      begin(table, [cols="2", border="0", width="100%"]),
		      begin(tbody), 
		      begin(tr),
		      td([align=left], Previous),
		      td([align=right], Next),
		      end(tr),
		      end(tbody),
		      end(table)
		  ].
